Утилита переименования подразделений
-------------------------------------

Введение
~~~~~~~~

.. important::

  Перед использованием утилиты рекомендуется ознакомиться с данной инструкцией в том порядке, как она изложена. Для понимания особенностей работы утилиты и во избежание нежелательных результатов не стоит переходить сразу к разделу примеров запуска. Утилита рассчитана на администраторов с уверенным знанием основ работы ``389ds`` и ``ldap``-операций в том числе опыт их вызова через консоль и анализа результатов стандартными средствами **Linux**. Утилита является **апробацией** более глубокого механизма 389ds -- переименования контейнеров, у которого в рамках текущей версии есть свои ограничения и особенности.

В версии **ALD Pro** 3.1.0 и ранее возможность переименовать организационное подразделение отсутствовала из-за определенных технических ограничений внутренних компонентов системы каталогов ``389ds``. В **ALD Pro** объекты не перемещаются физически во вложенные записи, вместо этого реализована их привязка через ссылочный **LDAP**-атрибут ``rbtadp`` типа ``DN``. Это дает обратную совместимость со структурой **FreeIPA** и другие преимущества, но вместе с тем затрудняет переименование организационных подразделений, так как:

* при выполнении переименования (как операции записи в **LDAP**-каталог) требуется в рамках одной транзакции в большинстве сценариев изменить значение атрибута ``rbtadp`` у всех связанных записей, что создает проблемы при большом числе объектов в каталоге и определенной конфигурации **LDAP**-каталога. Эта задача по поддержанию ссылочной целостности возлагается на плагин ``389ds`` -- ``referential-integrity-plugin``, который при изменении ``DN`` любого объекта обновляет и все связанные с этим ``DN`` ссылочные атрибуты, например, ``member``;

* После изменения атрибута ``rbtadp`` необходимо синхронизировать с ним значение атрибута ``rbtaou`` этого объекта. Эта задача также возлагается на плагин ``389ds`` -- ``watch-rbtadp``, он отслеживает изменения атрибутов ``rbtadp`` у объектов каталога и записывает в ``rbtaou`` его ``RDN``.

По этим же причинам средствами портала управления (на момент выпуска **ALD Pro** 3.1.0 и ранее) невозможно удаление или перенос непустого подразделения.

В рамках релиза **ALD Pro** 3.2.0 была разработана и внедрена возможность управления подразделениями со сложной иерархической структурой и большим числом объектов, которая учитывает значительную часть этих ограничений в виде CLI-утилиты. Выбор в пользу CLI-утилиты обусловлен сложностью в реализации функционала: системы каталога, в том числе **ALD Pro**, в первую очередь созданы для операции быстрого чтения, а не записи.

.. important::

  При необходимости переименовать\\перенести подразделение рекомендуется использовать данную утилиту, а не функционал портала управления.

Описание утилиты
~~~~~~~~~~~~~~~~

Добавлена CLI-утилита ``aldpro-move-ou``. С версии 3.2.0 доступна через терминал на контроллерах домена **ALD Pro**. Утилита предоставляет следующие возможности:

1. **Переименование подразделения:** добавлена возможность изменить имя подразделения (``RDN``).

  Например, подразделение с ``RDN`` ``ou=B``, расположенное в контейнере ``ou=domain-01.mycorp.ru,cn=orgunits,cn=accounts,dc=domain-01,dc=mycorp,dc=ru`` можно переименовать в ``ou=newname``. Подразделение сохранит свое положение в иерархии и его полный ``DN`` будет ``ou=B,ou=domain-01.mycorp.ru,cn=orgunits,cn=accounts,dc=domain-01,dc=mycorp,dc=ru``;

2. **Перенос подразделения:** добавлена возможность изменить родителя подразделения.

  Например, подразделение с ``RDN`` ``ou=B``, расположенное в контейнере ``ou=domain-01.mycorp.ru,cn=orgunits,cn=accounts,dc=domain-01,dc=mycorp,dc=ru`` можно переместить в контейнер ``ou=A,ou=domain-01.mycorp.ru,cn=orgunits,cn=accounts,dc=domain-01,dc=mycorp,dc=ru``. Подразделение сохранит свое ``RDN``, но изменит положение в иерархии подразделений, таким образом его полный ``DN`` ``ou=B,ou=A,ou=domain-01.mycorp.ru,cn=orgunits,cn=accounts,dc=domain-01,dc=mycorp,dc=ru``;

3. **Переименование и перенос подразделения:** добавлена возможность одновременно изменить родителя подразделения и его ``RDN``. 

  Например, подразделение с ``RDN`` ``ou=B``, расположенное в контейнере ``ou=domain-01.mycorp.ru,cn=orgunits,cn=accounts,dc=domain-01,dc=mycorp,dc=ru`` можно переместить в контейнер ``ou=A,ou=domain-01.mycorp.ru,cn=orgunits,cn=accounts,dc=domain-01,dc=mycorp,dc=ru`` и переименовать в ``ou=C``. Таким образом его полный ``DN`` ``ou=С,ou=A,ou=domain-01.mycorp.ru,cn=orgunits,cn=accounts,dc=domain-01,dc=mycorp,dc=ru``;

4. **Удаление подразделения вместе со всей вложенной иерархией:** добавлена возможность удаления подразделение вместе со всеми связанными с ним объектами. 

  .. important::

    Данное действие приведет к неизбежной и безвозвратной потере данных, поскольку все связанные с удаляемыми подразделениями объекты будут удалены без использования корзины. Корзина не поддерживает восстановление подразделений, групп и других объектов в **ALD Pro** 3.2.0. Рекомендуется с осторожностью использовать данный флаг и только в том случае, когда это действительно необходимо.

Входные данные
~~~~~~~~~~~~~~

Ниже приведено описание опций (флагов) утилиты:

* ``--action`` (required) -- действие с целевым подразделением (переименовать\\удалить). Два значения на выбор: [``delete``, ``rename``];
* ``--dn`` (required) ``DN`` целевого подразделения, которое необходимо удалить\\переместить\\переименовать;
* ``--newrdn`` (opt) -- новый ``RDN`` (имя объекта) для целевого подразделения, вида ``ou=<orgunit_name>``, используется для переименования подразделения;
* ``--newsuperior`` (opt) -- полный ``DN`` нового родительского подразделения для целевого, используется для переноса подразделения;
* ``--force`` (opt) РИСК. -- форсированное удаление подразделения, вне зависимости от наличия защиты от удаления. Используется только в связке с действием ``delete``.

.. _utilities_and_389ds:

Особенности работы утилиты и 389ds
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Переименование структурных подразделений связано с рядом особенностей и технологических ограничений в рамках релиза **ALD Pro** 3.2.0, которые необходимо учитывать перед тем как использовать утилиту. 

Базовый сценарий использования, на который рассчитана CLI-утилита -- переименование подразделения, связанного ссылочным атрибутом ``rbtadp`` не более чем со 100 000 объектов: пользователи, группы пользователей, компьютеры, группы компьютеров, роли). Например, если будет переименована иерархия из 10 подразделений, где каждое подразделение связано с 20 000 объектов, то это также базовый сценарий. 

.. note::

  100 000 объектов -- это значение ряда настраиваемых в ``389ds`` ``ns*`` лимитов на запись, чтение и другие операции. Это значение предустановлено, оно является защитой от чрезмерного использования вычислительных ресурсов и повышает надежность системы каталогов в отдельных ситуациях. Менять данные лимиты для создания организационного подразделения с более чем 100 000 объектов не рекомендуется. Вместо этого необходимо переработать организационную структуру и распределить объекты в несколько разных подразделений, при том они могут быть потомками исходного, здесь никаких ограничений нет. 

* **Длительность работы утилиты** будет напрямую зависеть от количества объектов в переносимом подразделении, hardware-особенностей сервера, где развернут контроллер домена (далее -- КД) **ALD Pro** (количество ядер, тактовая частота и т.п.). Для индикации прогресса операции утилита использует прогресс бар с предварительной оценкой времени обработки всей иерархии. Также существует зависимость настроек ``389ds`` (для информации):

  - ``referint-update-delay`` = 1. Настраивается в файле конфигурации плагина ``referential integrity plugin``, в ``cn=config``. Данная настройка отключает транзакционный режим работы плагина, что делает поддержку ссылочной целостности плагином долгой и асинхронной, но является необходимым условием для обработки подразделения с очень большим числом связанных ссылками ``rbtadp`` объектов;

  - ``nsslapd-threadnumber`` = N. Количество допустимых child-потоков, которые может запустить ``389ds``. Скорость обработки зависит от этого параметра и количества CPU-ядер на сервере **ALD Pro**;

* **При переименовании подразделения с >=100 тыс. объектов** необходимо вручную, с помощью средств прямого управления **LDAP**-каталогом (например CLI-утилитой ``ldapmodify``, вероятно с помощью ``cn=Directory Manager``) установить в настройках ``referential integrity`` плагина (``cn=config``) атрибут ``referint-update-delay`` = 1. Без установки данной настройки корректно завершить операцию не удастся, поскольку это также требует изменения лимитов ``dblocks``, ``idscanlimit`` для всего **LDAP**-каталога, что может нарушить стабильность работы каталога и не рекомендуется к использованию. 
Если настройки не были выставлены корректно и в каталоге большое число объектов, CLI-утилита выведет соответствующее сообщение об ошибке.

* **Утилита продолжит незавершенную штатно операцию** в случае возникновения непредвиденной исключительной ситуации. Статус предыдущей операции хранится в ``/opt/rbta/migration/aldpro-move-ou/move-ou.json`` на том же КД, где была запущена утилита ранее. При запуске утилиты проверяется наличие файла, содержащего данные о незаконченной операции. Если файл существует, утилита восстанавливает контекст и продолжает выполнение операции. В связи с этим для продолжения операции, утилита должна быть запущена на том же КД, где и изначально. Незавершенная операция может быть только одна.

* **При удалении защищенного подразделения** с помощью флага ``--action delete`` в операции будет отказано, при этом ни один объект не будет удален из системы каталогов. **При удалении незащищенного подразделения**, которое содержит хотя бы один защищенный объект будет отказано в операции, при этом ни один объект не должен быть удален из системы каталогов. Подробнее о защите объектов от случайного удаления в Руководстве Администратора ч.2 (Раздел будет добавлен позже).

* Ссылочный атрибут типа ``DN`` (``rbtadp``), который попадает на обработку плагину ``refint`` всегда и принудительно конвертируется в нижний регистр, что является стандартным поведением. 
  
* **ВАЖНО! После каждой операции переименования\переноса подразделения** (или одновременно и той и другой операции) необходимо перезагрузить КД командой ``ipactl restart``. Это, в рамках текущей версии пакета 389ds, необходимо для поддержания консистентности базы данных в случае нескольких операций переименования\переноса над одним и тем же подразделением. При удалении подразделения это не требуется.

Пререквизиты
~~~~~~~~~~~~~~~~

1. Утилита для корректной работы требует аутентификации под пользователем с ролью **ALDPRO - Main Administrator**, для которой в рамках релиза 3.2.0 добавлены необходимые привилегии и разрешения;

2. Убедиться, что в иерархии, которую планируется переименовывать нет подразделений с числом объектов более 100 000. В ином случае необходимо ознакомиться с разделом :ref:`utilities_and_389ds` и корректно настроить ``389ds``;

3. Активировать виртуальное окружение ``python``:
  
  .. code-block:: bash

    source /opt/rbta/venvs/aldpro-common/bin/activate

4. Получить привилегии суперпользователя ``sudo -i``;

5. Сгенерировать tgt-билет для того пользователя, который будет использован для работы утилиты ``kinit <username>``.

Запуск утилиты
~~~~~~~~~~~~~~~~

Вывод справки к утилите:

.. code-block:: bash

  aldpro-move-ou -h

Переименование подразделения ``ou=A`` в подразделение ``ou=X``:

.. code-block:: bash

  aldpro-move-ou --dn ou=A,ou=aldpro.domain.ru,cn=orgunits,cn=accounts,dc=aldpro,dc=domain,dc=ru --newrdn ou=X --action rename
  ipactl restart              

Перенос подразделения ``ou=A1,ou=A,ou=aldpro.domain.ru`` в ``ou=B,ou=aldpro.domain.ru``:

.. code-block:: bash

  aldpro-move-ou --dn ou=A1,ou=A,ou=aldpro.domain.ru,cn=orgunits,cn=accounts,dc=pool-xx,dc=aldpro,dc=domain,dc=ru --newsuperior ou=B,ou=aldpro.domain.ru,cn=orgunits,cn=accounts,dc=aldpro,dc=domain,dc=ru --action rename
  ipactl restart

Удаление подразделения ``ou=A`` вместе с иерархией объектов:

.. code-block:: bash

  aldpro-move-ou --dn ou=A,ou=aldpro.domain.ru,cn=orgunits,cn=accounts,dc=aldpro,dc=domain,dc=ru --action delete


Удаление подразделения ``ou=A`` вместе с иерархией защищенных от случайного удаления объектов:

.. code-block:: bash

  aldpro-move-ou --dn ou=A,ou=aldpro.domain.ru,cn=orgunits,cn=accounts,dc=aldpro,dc=domain,dc=ru --action delete

